
/**********************************************************************************\
** 文件名称: PID.c
** 创建人员: YCG
** 创建日期: 2018-12-16
** 文档描述:
P；提高响应速度
I；减小静态误差
D；抑制振荡

** 版本代号: V0.1
** 版本说明: 初始版本
\********************************************************************************/
#include "PID.h"


/*******************************************************************************
** 函数名称: PID_Init
** 功能描述: 初始化PID控制对象的系数
** 参数说明: pid: [输入/出] PID控制对象
**			 Kp: [输入/出] 比例系数
**			 Ki: [输入/出] 积分系数
**			 Kd: [输入/出] 微分系数
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-16
********************************************************************************/

void PID_Init(PID_t* const pid, uint8_t Mode, float Kp, float Ki, float Kd) {
    pid->Mode = Mode;
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
}

/*******************************************************************************
** 函数名称: PID_Position
** 功能描述:PID控制,放入定时器中执行
						位置式控制： Output=Kp*e(k)+Ki*∑e(k)+Kd[e（k）-e(k-1)]
						增量式控制： Output+=Kp[e（k）-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
						e(k)代表本次偏差
						e(k-1)代表上一次的偏差
						∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
** 参数说明: pid: [输入]      PID控制对象
**			     feedback: [输入] PID反馈信号
** 返回说明: None
** 创建人员: YCG
** 创建日期: 2018-12-16
********************************************************************************/
float PID_Scan(PID_t* const pid, float const feedback) {
	
    switch(pid->Mode) {
			
    case PID_MODE_Position:   //位置式控制
        pid->NowBias = feedback - pid->Target;    //本次反馈值与目标的偏差
        pid->AccBias += pid->NowBias ;            //累积本次的偏差
        pid->Output = (pid->Kp * pid->NowBias)
                      + (pid->Ki * pid->AccBias)
                      + (pid->Kd * (pid->NowBias - pid->LastBias)); //根据公式计算出pid
                pid->LastBias = pid->NowBias;      //保留这一次的差作为为下一次的LastBias使用
        break;

    case PID_MODE_Incremental: //增量式控制
        pid->NowBias = feedback - pid->Target;    //本次反馈值与目标的偏差

        pid->Output += ((pid->Kp * (pid->NowBias - pid->LastBias))
                        + (pid->Ki * pid->NowBias)
                        + (pid->Kd * (pid->NowBias - 2 * (pid->LastBias) + pid->AccBias))); //根据公式计算出pid

        pid->AccBias = pid->LastBias;     //保留上一次的偏差作为下一次的AccBias使用
        pid->LastBias = pid->NowBias;      //保留这一次的差作为为下一次的LastBias使用
        break;
    }
    return pid->Output;
}

/********************************End of File************************************/
